package systems.dla 
{
	import flash.geom.Point;
	import utils.GeomUtils;
	/**
	 * @author Nicolas Barradeau
	 * http://en.nicoptere.net
	 */
	public class DLAEmitter 
	{
		
		
		
		static private const POINT:String 	= 'point';
		static private const DISC:String 	= 'disc';
		static private const LINE:String 	= 'line';
		static private const POLY:String 	= 'poly';
		
		private var _type:String = POINT;
		
		
		static public const _INSIDE:String 		= 'in';
		static public const _OUTSIDE:String		= 'out';
		static public const _BOTH:String		= 'both';
		
		private var _emissionMode:String = _BOTH;
		
		
		static private const pi2:Number = Math.PI * 2;
		
		private var _speed:Number 			= 1;
		private var _angle:Number 			= NaN;
		private var radius:Number 			= 0;
		
		
		
		private var points:Vector.<Point>;
		
		
		
		public function DLAEmitter() { }
		
		
		
		static public function pointEmitter( p0:Point ):DLAEmitter
		{
			
			var e:DLAEmitter = new DLAEmitter();
			
			e.type = POINT;
			e.points = Vector.<Point>( [ p0 ] );
			e.emissionMode = _OUTSIDE;
			
			return e;
			
		}
		
		static public function discEmitter( p0:Point, radius:Number ):DLAEmitter
		{
			
			var e:DLAEmitter = new DLAEmitter();
			
			e.type = DISC;
			e.points = Vector.<Point>( [ p0 ] );
			e.radius = radius;
			e.emissionMode = _OUTSIDE;
			
			return e;
			
		}
		
		static public function lineEmitter( p0:Point, p1:Point ):DLAEmitter
		{
			
			var e:DLAEmitter = new DLAEmitter();
			
			e.type = LINE;
			e.points = Vector.<Point>( [ p0, p1 ] );
			e.emissionMode = _BOTH;
			
			return e;
			
		}
		
		
		
		
		public function emit():DLAParticle
		{ 
			
			var p:DLAParticle = new DLAParticle();
			
			var dist:Number
			angle = getAngle();
			var _angle:Number;
			
			switch( type )
			{
				case POINT:
				
					p.x = points[ 0 ].x;
					p.y = points[ 0 ].y;
					p.velocity.x = Math.cos( angle ) * speed;
					p.velocity.y = Math.sin( angle ) * speed;
				
				break;
				
				case DISC:
				
					_angle = Math.random() * pi2;
					
					p.x = points[ 0 ].x + Math.cos( _angle ) * radius;
					p.y = points[ 0 ].y + Math.sin( _angle ) * radius;
					
					_angle = GeomUtils.angle( points[ 0 ], p );
					
					p.velocity.x = Math.cos( _angle + angle ) * speed;
					p.velocity.y = Math.sin( _angle + angle ) * speed;
					
				break;
				
				case LINE:
				
					dist = ( GeomUtils.distance( points[ 0 ], points[ 1 ] ) * Math.random() );
					_angle = GeomUtils.angle( points[ 0 ], points[ 1 ] );
					
					p.x = points[ 0 ].x + Math.cos( _angle ) * dist;
					p.y = points[ 0 ].y + Math.sin( _angle ) * dist;
					
					p.velocity.x = Math.cos( _angle + angle ) * speed;
					p.velocity.y = Math.sin( _angle + angle ) * speed;
					
				break;
				
				case POLY:
				break;
			}
			return p;
		}
		
		private function getAngle():Number
		{
			
			switch( type )
			{
				case POINT:
					return Math.random() * pi2;
				break;
				
				case DISC:
					switch( emissionMode )
					{
						case _INSIDE: return -Math.PI;
						case _OUTSIDE: return 0;
						case _BOTH: return ( ( Math.random() <.5 ) ? Math.PI : 0 );
					}
				break;
				
				case LINE:
				case POLY:
				
					switch( emissionMode )
					{
						case _INSIDE: return Math.PI / 2;
						case _OUTSIDE: return -Math.PI / 2;
						case _BOTH: return Math.PI / 2 * ( ( Math.random() <.5 ) ? 1 : -1 );
					}
					
				break;
			}
			return 0;
		}
		
		public function get type():String { return _type; }
		public function set type(value:String):void 
		{
			_type = value;
		}
		
		public function get speed():Number { return _speed; }
		
		public function set speed(value:Number):void 
		{
			_speed = value;
		}
		
		public function get angle():Number { return _angle; }
		
		public function set angle(value:Number):void 
		{
			_angle = value;
		}
		
		public function get emissionMode():String { return _emissionMode; }
		
		public function set emissionMode(value:String):void 
		{
			_emissionMode = value;
		}
		
		
	}

}